package com.zhiche.wms.service.stock.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.domain.mapper.inbound.InboundNoticeHeaderMapper;
import com.zhiche.wms.domain.mapper.inbound.InboundNoticeLineMapper;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.mapper.outbound.OutboundNoticeHeaderMapper;
import com.zhiche.wms.domain.mapper.outbound.OutboundNoticeLineMapper;
import com.zhiche.wms.domain.mapper.stock.StockMapper;
import com.zhiche.wms.domain.mapper.sys.SysConfigMapper;
import com.zhiche.wms.domain.model.inbound.InboundNoticeHeader;
import com.zhiche.wms.domain.model.inbound.InboundNoticeLine;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.outbound.OutboundNoticeHeader;
import com.zhiche.wms.domain.model.outbound.OutboundNoticeLine;
import com.zhiche.wms.domain.model.stock.Stock;
import com.zhiche.wms.domain.model.sys.SysConfig;
import com.zhiche.wms.service.constant.PutAwayType;
import com.zhiche.wms.service.constant.ShipType;
import com.zhiche.wms.service.constant.SourceSystem;
import com.zhiche.wms.service.inbound.IInboundPutawayHeaderService;
import com.zhiche.wms.service.outbound.IOutboundShipLineService;
import com.zhiche.wms.service.stock.AutoInAndOutBoundService;
import com.zhiche.wms.service.utils.CommonValueConstant;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: caiHua
 * @Description: 仓库无人值守，自动入库/出库
 * @Date: Create in 15:37 2018/12/14
 */
@Service
public class AutoInAndOutBoundServiceImpl extends ServiceImpl<StockMapper, Stock> implements AutoInAndOutBoundService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AutoInAndOutBoundServiceImpl.class);

    @Autowired
    private IInboundPutawayHeaderService putawayHeaderService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    private OutboundNoticeLineMapper outboundNoticeLineMapper;
    @Autowired
    private OutboundNoticeHeaderMapper outboundNoticeHeaderMapper;
    @Autowired
    private InboundNoticeLineMapper inboundNoticeLineMapper;
    @Autowired
    private InboundNoticeHeaderMapper inboundNoticeHeaderMapper;
    @Autowired
    private IOutboundShipLineService outboundShipLineService;

    @Override
    public void unattendedAutoWareHouse(Map<String, String> condition) {
        //1、检查入参是否合法
        this.checkAutoWareHouse(condition);

        //2、查询仓库看守状态
        Long noticeLineId = this.queryStoreStatus(condition, CommonValueConstant.INBOUND);
        LOGGER.info("需要入库的入库通知单id为：{}", noticeLineId);

        //3、自动入库通知
        if (Objects.isNull(noticeLineId)) {
            return;
        }
        putawayHeaderService.updateByNoticeLineId(noticeLineId, PutAwayType.BLIND_PUTAWAY, SourceSystem.HONEYWELL, null);
    }

    @Override
    public void unattendedAutoOutBound(Map<String, String> condition) {
        //1、检查出库入参是否合法
        this.checkAutoWareHouse(condition);

        //2、查询仓库出库看守状态
        Long outNoticeLinedId = this.queryStoreStatus(condition, CommonValueConstant.OUTBOUND);
        LOGGER.info("需要出库的出库通知单id为：{}", outNoticeLinedId);

        //3、自动出库通知
        if (Objects.isNull(outNoticeLinedId)) {
            return;
        }
        outboundShipLineService.shipByNoticeLineId(outNoticeLinedId, ShipType.BLIND_SHIP, SourceSystem.HONEYWELL);
    }


    /**
     * 无人看守，自动入库，入参判断
     *
     * @param condition 入参集合
     * @return
     */
    private Map<String, String> checkAutoWareHouse(Map<String, String> condition) {
        //shipmentGid为调度指令ID
        if (StringUtils.isEmpty(condition.get("shipmentGid"))) {
            throw new BaseException("调度指令id不能为空");
        }
        return condition;
    }

    /**
     * 通过车架号和指令id查询系统单号
     *
     * @param shipmentGid 指令id
     * @param vin         车架号
     * @return 系统单号 shipmentGid
     */
    private String getReleaseGidByVin(String shipmentGid, String vin) {
        if (StringUtils.isEmpty(shipmentGid)) {
            throw new BaseException( "入参指令id【shipmentGid】不能为空");
        }
        //车架号
        if (StringUtils.isEmpty(shipmentGid)) {
            throw new BaseException( "入参车架号【vin】不能为空");
        }
        //通过指令id和车架号查询release_gid
        Wrapper<OtmOrderRelease> otmOrderReleaseWrapper = new EntityWrapper<>();
        otmOrderReleaseWrapper.eq("vin", vin);
        otmOrderReleaseWrapper.eq("shipment_gid", shipmentGid);
        otmOrderReleaseWrapper.ne("status",TableStatusEnum.STATUS_50.getCode());
        otmOrderReleaseWrapper.orderBy("gmt_create", false);
        List<OtmOrderRelease> otmOrderRelease = otmOrderReleaseMapper.selectList(otmOrderReleaseWrapper);
        if (CollectionUtils.isEmpty(otmOrderRelease)) {
            throw new BaseException("运单信息为空");
        }
        return otmOrderRelease.get(0).getReleaseGid();
    }

    private Long queryStoreStatus(Map<String, String> condition, String storeFlag) {
        Long lineId = null;
        //1、系统单号不为空
        String releaseGid = condition.get("releaseGid");
        if (StringUtils.isEmpty(releaseGid)) {
            //2、系统单号为空
            //调度指令ID
            releaseGid = this.getReleaseGidByVin(condition.get("shipmentGid"), condition.get("vin"));
        }
        if (storeFlag.equals(CommonValueConstant.INBOUND)) {
            lineId = this.queryInBoundSysConfig(releaseGid);
        } else if (storeFlag.equals(CommonValueConstant.OUTBOUND)) {
            lineId = this.queryOutBoundSysConfig(releaseGid);
        }
        return lineId;
    }

    /**
     * 查询自动入库是否配置了无人值守
     *
     * @param releaseGid
     */
    private Long queryInBoundSysConfig(String releaseGid) {
        Long lineId = null;
        //1、查询入库通知单头heard_id
        InboundNoticeLine inboundNoticeLineParam = new InboundNoticeLine();
        inboundNoticeLineParam.setLineSourceKey(releaseGid);
        EntityWrapper<InboundNoticeLine> ew = new EntityWrapper<>();
        ew.eq("line_source_key",releaseGid);
        ew.ne("status",TableStatusEnum.STATUS_50.getCode());
        List<InboundNoticeLine> inboundNoticeLines = inboundNoticeLineMapper.selectList(ew);
        if (CollectionUtils.isEmpty(inboundNoticeLines)) {
            throw new BaseException("入库通知明细结果为空！");
        }
        InboundNoticeLine inboundNoticeLine = inboundNoticeLines.get(0);
        //10:未入库,30:全部入库,50:取消
        String lineStatus = inboundNoticeLine.getStatus();
        LOGGER.info("系统单号releaseGid：{},查询的入库通知单状态为:{}", releaseGid, lineStatus);
        if (CommonValueConstant.INBOUND_NOTICE_LINE_10.equals(lineStatus)) {
            //2、通过第1步获取到的heard_id到入库通知单头表查询store_house_id
            InboundNoticeHeader inboundNoticeHeader = inboundNoticeHeaderMapper.selectById(inboundNoticeLine.getHeaderId());
            Long storeId = inboundNoticeHeader.getStoreHouseId();

            //3、查询是否配置无人值守
            SysConfig sysConfig = this.getBountConfig(storeId, CommonValueConstant.NOPERSON_INBOUND);
            if (null == sysConfig) {
                LOGGER.info("没有配置无人值守的数据");
                return null;
            }
            lineId = inboundNoticeLine.getId();
        }
        return lineId;
    }

    /**
     * 查询出库是否配置了无人值守
     *
     * @param releaseGid
     */
    private Long queryOutBoundSysConfig(String releaseGid) {
        Long lineId = null;
        //1、查询入库通知单头heard_id
        EntityWrapper<OutboundNoticeLine> ew = new EntityWrapper<>();
        ew.eq("line_source_key",releaseGid);
        ew.ne("status",TableStatusEnum.STATUS_50.getCode());
        List<OutboundNoticeLine> outboundNoticeLines = outboundNoticeLineMapper.selectList(ew);
        if (CollectionUtils.isEmpty(outboundNoticeLines)) {
            throw new BaseException("出库通知明细结果为空！");
        }
        OutboundNoticeLine outboundNoticeLine = outboundNoticeLines.get(0);
        //10:未入库,30:全部入库,50:取消
        String lineStatus = outboundNoticeLine.getStatus();
        LOGGER.info("系统单号releaseGid：{},查询的出库通知单状态为:{}", releaseGid, lineStatus);
        if (CommonValueConstant.OUTBOUND_NOTICE_LINE_10.equals(lineStatus) || CommonValueConstant.OUTBOUND_NOTICE_LINE_20.equals(lineStatus)) {
            //2、通过第1步获取到的heard_id到入库通知单头表查询store_house_id
            OutboundNoticeHeader outboundNoticeHeader = outboundNoticeHeaderMapper.selectById(outboundNoticeLine.getHeaderId());
            Long storeId = outboundNoticeHeader.getStoreHouseId();

            //3、查询是否配置无人值守
            SysConfig sysConfig = this.getBountConfig(storeId, CommonValueConstant.NOPERSON_OUTBOUND);
            if (null == sysConfig) {
                LOGGER.info("没有配置无人值守的数据");
                return null;
            }
            lineId = outboundNoticeLine.getId();
        }
        return lineId;
    }

    /**
     * 是否配置了无人值守配置项
     *
     * @param storeId
     * @return
     */
    private SysConfig getBountConfig(Long storeId, String boundConfigFlag) {
        SysConfig sysConfigParam = new SysConfig();
        sysConfigParam.setConfiged(CommonValueConstant.CONFIGED_1);
        sysConfigParam.setCode(boundConfigFlag);
        sysConfigParam.setConfigType(CommonValueConstant.CONFIG_TYPE_WAREHOUSE);
        sysConfigParam.setReleationId(String.valueOf(storeId));
        sysConfigParam.setConfigLevel(TableStatusEnum.STATUS_2.getCode());
        return sysConfigMapper.selectOne(sysConfigParam);
    }

}
